package com.vivi.codereview.tools;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import com.vivi.codereview.WhatTheFuckException;

public class SystemHandler {

  /**
   * regular expression for files we want to consider
   */
  public static final String FILE_REGEXP = ".+\\.(java|xml|cat|mdl)";

  public String getFileRegexp() {
    return FILE_REGEXP;
  }

  public Process launchCommand(String dir, String command) throws Exception {
    Log.log("Processing: " + dir + " > " + command, Log.D);
    ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/C", command);
    builder.environment();
    builder.directory(new File(dir));
    return builder.start();
  }

  /**
   * run command and return all execution output lines in a list of String
   *
   * @param dir
   * @param command
   * @param log
   * @return
   * @throws IOException
   */
  public List<String> launchCommandAndGetOutput(String dir, String command) throws Exception {
    ArrayList<String> result = new ArrayList<String>();
    Process process = null;
    try {
      process = launchCommand(dir, command);
      InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream());
      BufferedReader input = new BufferedReader(inputStreamReader);
      String line;
      while ((line = input.readLine()) != null) {
        result.add(line);
      }
      // wait for the error output to end
      process.waitFor();
    }
    catch (InterruptedException e) {
      Log.log("Process interrupted", Log.E);
      throw new WhatTheFuckException(Log.Exit.EXTERN_PROCESS_INTERRUPTED);
    }
    finally {
      if (process != null) {
        process.destroy();
        process = null;
      }
    }
    Log.log("Command " + command + " returned:\n\n" + result + "\n\n", Log.DD);
    return result;
  }

  public File getFile(String root, String filename) throws Exception {
    return new File(getFullFilename(root, filename));
  }

  public String getFullFilename(String root, String filename) throws Exception {
    return root + File.separator + filename;
  }

  public boolean isReadOnly(File file) throws Exception {
    return !file.canWrite();
  }

  public Document readXmlFile(File file) throws ParserConfigurationException, SAXException, IOException {
    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
    Document document = documentBuilder.parse(file);
    return document;
  }
}
